#! /usr/bin/env python
# -*- coding:utf-8 -*-

'''
author :ben
date : 2018-1-xx

sindy(qq):2771429254
QQ: 2835579534
Python学习交流群 602319259

报名链接：
https://ke.qq.com/course/211893
vip系统课程:现活动价:5380  (原价7680)
'''


# 函数

# 1.为什么要用函数,函数是什么?
# 2.函数怎么用?
# 3.函数的返回值---->可以返回多个值?
# 8.参数的类型
# 9.全局变量和局部变量
# 4.默认参数
# 5.关键字参数
# 6.动态可收集参数
# 7.匿名函数




# 代码的封装:--->提高了代码的复用性
# 当前模块可以用,其他模块也可以通过导入的方式使用
# 私有函数---->范围,作用域--->面对对象
# def fun():
#     # 200行代码--->功能-->重复写一次,复制
#     pass

# 关键字def
# def make():
#     pass    # pass占位符,没有代码,
# a = make()   #
# print(a)

# python3.6(3.x版本)不支持元祖参数的解包
# 2.x---->支持
# def make(a,(b,c)):
#     print(11)
# make(1,(2,3))

# 函数名,标识符的命名---->
# 驼峰规则:
# 当前函数名称比较长
# def get_user_name():  #
#     pass
# def getUserName():   #
#     pass

# 函数的多个返回值
# def get_num(x, y):
#     z = x + 3
#     w = y * 2
#     u = z + w
#     return z, w, u  # (注意)
#
# x, y, _ = get_num(2, 3)  # 课件(大家没看)
# print(x, y)
#  _,_, _ = get_num(3,4)  # ?--->没有接受返回的任何值?


# 参数类型
# 内置函数isinstance--->判断对象--->指定类型(子类)
# class Person():
#     pass
#
# class Man(Person):
#     pass
# 有些时候对于传递进来的参数的类型做出判断
# def get_num(x):
#     if not isinstance(x,(int,float)):
#         print('参数类型错误')
#     elif isinstance(x,float):
#         print(abs(round(x)))
#         print(11)
#     elif isinstance(x,int):
#         if x < 0:
#             print(abs(x))
#             print(222)
#         else:
#             print(x)
#             print(333)
# get_num(8)

# 函数个数的问题:
# get_num(1,2,3)   # 定义和调用的时候参数的个数要对应


# 全局变量和局部变量
# num = 8   # 全局变量
# def make():
#     num = 22   # 局部变量(可见范围在函数体内)
#     print(num)   # 22
#
# make()
# print(num)  #  函数外--->全局变量   8

# global关键字的用法
# num = 8   # 全局变量
# def make():
#     global num    # 不再是局部,而是全局
#     num = 22   # 局部变量(可见范围在函数体内)
#     print(id(num))    # 1838116992
#     print(num)   # 22
#
# # make()
# print(num) #?
# print(id(num))   #  1838116992



# 参数的陷阱?
# def make_list(s=[]):
#     print(id(s))
#     s.append('ben')
#     return s
# print(make_list([1,2,3]))   #z [1, 2, 3, 'ben']
# print(make_list([5,6,7]))   # [5, 6, 7, 'ben']
# 正常没有问题
# 看看另外的情况?
# print(make_list())   # 正常      ['ben']                         43020488
# print(make_list())  # ?----->   ['ben', 'ben']---->参数的陷阱??   43020488
# 内存地址值相同--->
# []---->['ben']---->['ben','ben']  # 牢记在心
# 默认参数---->不可变对象(1)


# 默认参数--->定义函数的时候
# def get_sum(x, y=1):
#     return x + y
#
# print(get_sum(2))  #
# print(get_sum(3, 4))


# 关键字参数--->调用函数的时候
# def get_num(x, y, z=5):
#     return x + y + z
# print(get_num(1, 2))  # 默认参数
# print(get_num(2, 3, 8))  # 替换默认参数
# print(get_num(z=1, x=2, y=3))   # 关键字参数的用法(调用函数,参数的顺序更加灵活)


# 动态收集参数:*(元组)----->**(字典)
# def get_num(*nums):
#     print(type(nums))   #<class 'tuple'>
#     sum = 0
#     for num in nums:
#         sum += num    # 元组,报错的原因
#     print(sum)
#     return sum


#
# a_tuple = (1, 2, 3, 4, 5)  # 初始化  元组一个整体--->nums((1, 2, 3, 4, 5))
# get_num(a_tuple)
# get_num(1, 2, 3, 4)   # 1, 2, 3, 4--->nums元组--->nums(1,2,3,4)
# 报错问题怎么解决?
# a_tuple = (1, 2, 3, 4, 5)  # 初始化  元组一个整体--->nums((1, 2, 3, 4, 5))
# get_num(*a_tuple)   # 添加了一个星号  (1,2,3,4,5)


# 两个**---->**(字典)dict
#def work(**kw):  #
#    print(type(kw))
#    if 'name' in kw:  # <class 'dict'>
#        print('包含name参数')
#    if 'age' in kw:
#        print('包含age参数')


# 两种方式调用?
# work(name='ben',age=22)   # 关键字参数传递进来包装成字典dict
# a_dict = {'name':'ben','age':22}
# # print(**a_dict)  # 调用函数
# work(**a_dict)   #  先解包

# def fun(a, b, c=1, *args, **kw):
#     print('a=', a, 'b=', b, 'c=', c, 'args=', args, 'kw=', kw)
#
# fun(1,2)   # a= 1 b= 2 c= 1 agrs= () kw= {}
# fun(1,2,3)   # a= 1 b= 2 c= 3 agrs= () kw= {}
# fun(1,2,3,4,5,6)  # a= 1 b= 2 c= 3 args= (4, 5, 6) kw= {}  # 重点
# fun(1,2,3,4,5,name='ben')   # a= 1 b= 2 c= 3 args= (4, 5) kw= {'name': 'ben'}  # 重点


# 匿名函数  lambda关键字  没有名称,只使用一次
# func = lambda x,y:x+y   # 表达式
# # print(type(func))  # <class 'function'>
# # result = func(1,2)
# # print(result)
# def num(x,y):    # 留下函数引用(函数名)  可以多次使用
#     return x+y
# result = num(1,2)
# print(result)

# def get_num(x,y):  #
#     return x+y
# def call_fun(fun,p1,p2):  # 第二个函数内执行第一个函数
#     result = fun(p1,p2)
#     return result
#
# # print(call_fun(get_num,2,3))
# print(call_fun(lambda x,y:x+y,2,3))  # 只用一次
# print(call_fun(lambda x,y:x*y,4,5))
#
# num = 99
# num_list = [1] # 容器里面的元素(地址)
# print(id(num))  # 1817999904

#a_dict = {'a':20,'b':22}
#print(a_dict.items())
# ('a',20)---->x--->x[1]--->20
# ('b',22)---->x--->x[1]--->22
#sorted(a_dict.items(),key=lambda x:x[1])
#key= lambda x:x[1]   # 对应的索引1元素
#print(type(key))   # <class 'function'>
